/*
MIT License

Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo
*/

/*! \file Утилита тестирования средств работы с JSON библиотеки SIMODO core. Проект SIMODO.
*/

#include "simodo/variable/json/Serialization.h"
#include "simodo/variable/json/parser/JsonRdp.h"
#include "simodo/variable/json/parser/Json5Rdp.h"
#include "simodo/variable/json/parser/JsonLspBuilder.h"
#include "simodo/inout/reporter/ConsoleReporter.h"
#include "simodo/inout/convert/functions.h"

#include <iostream>

using namespace simodo::inout;
using namespace simodo::variable;

namespace
{
    int jsonize (Parser_interface & parser, const std::vector<Token> & const_variable_set, const std::vector<std::pair<Token,Token>> & group_set)
    {
        bool ok = parser.parse();

        if (ok) {
            std::cout << "Константы и переменные:" << std::endl;
            for(const Token & t : const_variable_set)
                std::cout << "\t\"" << toU8(t.lexeme()) << "\"\t" 
                          << getLexemeTypeName(t.type())
                          << ", [" 
                          << t.location().range().start().line() << ", " << t.location().range().start().character() 
                          << "]" << std::endl;
            std::cout << "Структура:" << std::endl;
            for(const auto & [open_brace_token,close_brace_token] : group_set)
                std::cout << "\t" << toU8(open_brace_token.lexeme()) << " ["
                          << open_brace_token.location().range().start().line() << ", " << open_brace_token.location().range().start().character()
                          << "], [" 
                          << close_brace_token.location().range().start().line() << ", " << close_brace_token.location().range().start().character()
                          << "] " << toU8(close_brace_token.lexeme()) << std::endl;
        }

        return ok ? 0 : 1;
    }
}

int main(int argc, char *argv[])
{
    std::vector<std::string> arguments(argv + 1, argv + argc);

    std::string	file_name = "";
    bool	    error     = false;
    bool	    help      = false;

    for(size_t i=0; i < arguments.size(); ++i)
    {
        const std::string & arg = arguments[i];

        if (arg[0] == '-')
        {
            if (arg == "--help" || arg == "-h")
                help = true;
            else
                error = true;
        }
        else if (file_name.empty())
            file_name = arg;
        else
            error = true;
    }

    if (!help && file_name.empty())
        error = true;

    if (error)
    {
        std::cout << "Ошибка в параметрах запуска" << std::endl;
        help = true;
    }

    if (help)
        std::cout   << "Утилита тестирования средств работы с JSON. Проект SIMODO." << std::endl
                    << "Формат запуска:" << std::endl
                    << "    <имя утилиты> [<параметры>] <файл>" << std::endl
                    << "Параметры:" << std::endl
                    << "    -h | --help - отображение подсказки по запуску программы" << std::endl
                    ;

    if (error)
        return 1;

    if (file_name.empty())
        return 0;

    ConsoleReporter                     reporter;
    std::vector<Token>                  const_variable_set;
    std::vector<std::pair<Token,Token>> group_set;
    JsonLspBuilder                      builder(const_variable_set, group_set);
    Value                               value;
    std::unique_ptr<Parser_interface>   parser;

    if (file_name[file_name.size()-1] == '5')
        parser = std::make_unique<Json5Rdp>(reporter, builder, file_name, value);
    else
        parser = std::make_unique<JsonRdp>(reporter, builder, file_name, value);

    return jsonize(*parser, const_variable_set, group_set);
}
